package cn.iocoder.yudao.module.system.controller.admin.a_audio_and_video;

import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.system.config.tools.FFmpegTools;
import cn.iocoder.yudao.module.system.controller.admin.a_audio_and_video.vo.*;
import cn.iocoder.yudao.module.system.controller.admin.a_pictures.vo.FileBaseVO;
import cn.iocoder.yudao.module.system.dal.dataobject.a_audio_and_video.AudioAndVideoDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.a_ai.service.AIService;
import cn.iocoder.yudao.module.system.service.a_audio_and_video.AudioAndVideoService;
import cn.iocoder.yudao.module.system.service.a_audio_and_video.AudioUploadServiceImpl;
import cn.iocoder.yudao.module.system.service.a_audio_and_video.VideoUploadServiceImpl;
import cn.iocoder.yudao.module.system.service.a_ids.IdsService;
import cn.iocoder.yudao.module.system.service.a_pictures.ImageUploadServiceImpl;
import cn.iocoder.yudao.module.system.service.ivrs.IvrsService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.alibaba.cloud.commons.lang.StringUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;


/**
 * @author lxj
 */
@Tag(name = "管理后台 - 稿件管理 - 音视频")
@RestController
@RequestMapping("/system/audioAndVideo")
@Validated
@Slf4j
public class AudioAndVideoController {

    @Value("${file.temp}")
    private String temp;

    @Value("${file.video.cover.path}")
    private String path;

    @Value("${file.video.cover.host}")
    private String host;

    @Resource
    AIService aiService;

    @Resource
    IvrsService ivrsService;

    @Resource
    private IdsService idsService;

    @Resource
    private FFmpegTools fFmpegTools;

    @Resource
    private AdminUserService adminService;

    @Resource
    private AudioAndVideoService audioAndVideoService;

    @Resource
    ImageUploadServiceImpl imageUploadService;

    @Resource
    AudioUploadServiceImpl audioUploadService;

    @Resource
    VideoUploadServiceImpl videoUploadService;

    @PostMapping("/updateReview")
    @Operation(summary = "提交审核")
    @PreAuthorize("@ss.hasPermission('system:audioAndVideo:update')")
    public CommonResult<Boolean> updateReview(@RequestParam("id") String id) {
        return success(audioAndVideoService.updateReview(id, 1));
    }

    @PostMapping("/updateShare")
    @Operation(summary = "共享素材")
    @PreAuthorize("@ss.hasPermission('system:audioAndVideo:update')")
    public CommonResult<Boolean> updateShare(@RequestParam("id") String id, @RequestParam("shareStatus") String shareStatus) {
        return success(audioAndVideoService.updateShare(id, shareStatus));
    }

    @PostMapping("/updatePush")
    @Operation(summary = "推送资源库")
    @PreAuthorize("@ss.hasPermission('system:audioAndVideo:update')")
    public CommonResult<Boolean> updatePush(@RequestParam("id") String id, @RequestParam("pushStatus") String pushStatus) {
        return success(audioAndVideoService.updatePush(id, pushStatus));
    }

    @PutMapping("/updateQukanUrl")
    @Operation(summary = "更新趣看视频")
    @PermitAll
    @ResponseBody
    public CommonResult<Boolean> updateQukanUrl(@RequestHeader Map<String, String> headers, @org.springframework.web.bind.annotation.RequestBody Map<String, String> data) {
        AudioAndVideoDO audioAndVideoDO = audioAndVideoService.get(data.get("id"));
        log.info("更新趣看视频 - audioAndVideoDO:{}", audioAndVideoDO);
        if (StringUtils.isEmpty(idsService.getUserName(headers.get("trsidsssosessionid")))) {
            log.info("更新趣看视频 - 当前用户不存在:{}");
            return error(500, "当前用户不存在");
        }
        log.info("更新趣看视频 - QukanUrl:{}", data.get("qukanUrl"));
        log.info("更新趣看视频 - QukanVideoCoverUrl:{}", data.get("qukanVideoCoverUrl"));
        audioAndVideoDO.setQukanUrl(data.get("qukanUrl"));
        audioAndVideoDO.setQukanVideoCoverUrl(data.get("qukanVideoCoverUrl"));
        return success(audioAndVideoService.updateQukanUrl(audioAndVideoDO));
    }

    @GetMapping("/pageQukan")
    @Operation(summary = "获取视频列表-趣看")
    @PermitAll
    public CommonResult<PageResult<AudioAndVideoQukanPageReqVO>> getQukanPage(@RequestHeader Map<String, String> headers, @RequestBody AudioAndVideoPageReqVO pageReqVO) {
        String userName = idsService.getUserName(headers.get("trsidsssosessionid"));
        if (StringUtils.isEmpty(userName)) {
            return error(200, "当前用户不存在");
        }
        AdminUserDO userByUsername = adminService.getUserByUsername(userName);
        if (userByUsername.getId() == null) {
            return error(500, "当前用户不存在");
        }
        log.info("获取视频列表-趣看 - 执行查询getPageByQukan:{}", userByUsername.getId());
        PageResult<AudioAndVideoQukanPageReqVO> pageResult = audioAndVideoService.getPageByQukan(pageReqVO, userByUsername.getId());
        return success(pageResult);
    }

    @GetMapping("/getQukan")
    @Operation(summary = "获取音视频详情-趣看")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PermitAll
    public CommonResult<AudioAndVideoReqVO> get(@RequestHeader Map<String, String> headers, @RequestParam("id") String id) {
        String userName = idsService.getUserName(headers.get("trsidsssosessionid"));
        if (StringUtils.isEmpty(userName)) {
            return error(500, "当前用户不存在");
        }
        log.info("获取音视频详情-趣看 - 执行getByQukan - 查询id为:{}", id);
        return success(audioAndVideoService.getByQukan(id));
    }

    @PostMapping("/upload")
    @Operation(summary = "上传文件")
    @OperateLog(logArgs = false) // 上传文件，没有记录操作日志的必要
    public CommonResult<String> uploadFile(FileUploadNewReqVO uploadReqVO) throws Exception {
        return success(audioAndVideoService.createFile(uploadReqVO));
    }

    @PostMapping("/audioUpload")
    @Operation(summary = "音频上传")
    @PreAuthorize("@ss.hasPermission('system:audioAndVideo:create')")
    public CommonResult<FileBaseVO> audioUpload(@RequestParam("file") MultipartFile file){
        return CommonResult.success(audioUploadService.upload(file));
    }

    @PostMapping("/videoUpload")
    @Operation(summary = "视频上传")
    public CommonResult<FileBaseVO> videoUpload(@RequestParam("file") MultipartFile file){
        return CommonResult.success(videoUploadService.upload(file));
    }

    @PostMapping("/uploadChunk")
    @Operation(summary = "分片上传")
    public CommonResult<Boolean> uploadChunk(int chunkNumber, int chunkTotal, MultipartFile file, String fileMD5) {
        return CommonResult.success(videoUploadService.uploadChunk(chunkNumber, chunkTotal, file, fileMD5, temp));
    }

    @GetMapping("/audioMerge")
    @Operation(summary = "合并音频分片", description = "合并音频分片")
    public CommonResult<AudioRespVO> audioMerge(@RequestParam("uuid") String uuid,
                                           @RequestParam("chunkTotal") int chunkTotal,
                                           @RequestParam("fileSize") Long fileSize,
                                           @RequestParam("ext") String ext) {
        return CommonResult.success(audioUploadService.merge(uuid, chunkTotal, fileSize, ext));
    }

    @GetMapping("/videoMerge")
    @Operation(summary = "合并视频分片", description = "合并视频分片")
    public CommonResult<VideoRespVO> videoMerge(@RequestParam("uuid") String uuid,
                                                @RequestParam("chunkTotal") int chunkTotal,
                                                @RequestParam("fileSize") Long fileSize,
                                                @RequestParam("ext") String ext) {
        return CommonResult.success(videoUploadService.merge(uuid, chunkTotal, fileSize, ext));
    }

    @PostMapping("matting/human")
    @Operation(summary = "智能剪辑")
    @OperateLog(enable = false)
    public CommonResult<String> mattingHumanVideo(@RequestParam String url) {
        String prefix = "/opt/DL-IVRS-V9-GPU_20240527";
        return success(ivrsService.mattingHumanVideo(prefix + url));
    }

    @PutMapping("/save")
    @Operation(summary = "音视频保存")
    @PreAuthorize("@ss.hasPermission('system:audioAndVideo:update')")
    public CommonResult<String> save(@Valid AudioAndVideoBaseVO baseVO) {
        try {
            System.out.println("传参："+baseVO.toString());
            return CommonResult.success(audioAndVideoService.save(baseVO));
        } catch (IOException e) {
            e.printStackTrace();
            throw exception(new ErrorCode(50000, "系统错误，请检查文件是否上传正确！"));
        }
    }

    @DeleteMapping("/deleteById")
    @Operation(summary = "根据id删除")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('system:audioAndVideo:delete')")
    public CommonResult<Boolean> deleteById(@org.springframework.web.bind.annotation.RequestBody Long[] ids) {
        return CommonResult.success(audioAndVideoService.delete(ids));
    }

    @GetMapping("/select/page")
    @Operation(summary = "获得分页")
    @PreAuthorize("@ss.hasPermission('system:audioAndVideo:query')")
    public CommonResult<PageResult<AudioAndVideoDO>> selectPage(@Valid AudioAndVideoPageReqVO pageReqVO) {
        PageResult<AudioAndVideoDO> pageResult = audioAndVideoService.selectPage(pageReqVO);
        return success(pageResult);
    }

    @GetMapping("/audioCutter")
    @Operation(summary = "音频剪裁")
    public CommonResult<Boolean> audioCutter(Long id, String startTime, String duration) {
        return success(audioAndVideoService.audioCutter(id, startTime, duration));
    }

    @GetMapping("/videoCutter")
    @Operation(summary = "视频剪裁")
    public CommonResult<Boolean> videoCutter(String input, String startTime, String duration) {
        return success(audioAndVideoService.videoCutter(input, startTime, duration));
    }

    @GetMapping("/transcodeMP3")
    @Operation(summary = "音频转码")
    public CommonResult<Boolean> transcodeMP3(String input, int bitRate, String out) {
        return success(fFmpegTools.transcodeMP3(input, bitRate, out));
    }

    @PostMapping("/cover/upload")
    @Operation(summary = "上传视频封面图片")
    public CommonResult<String> uploadCover(FileUploadNewReqVO uploadReqVO) {
        return CommonResult.success(imageUploadService.upload(uploadReqVO.getFile(), path, host));
    }

    @GetMapping("/updateDuration")
    @Operation(summary = "修改剪辑后音频时长")
    public CommonResult<Boolean> updateDuration(Long id) {
        return success(audioAndVideoService.updateDuration(id));
    }

    /**
     * 通过id获取音视频下载地址
     */
    @Transactional
    @GetMapping("/getAudioAndVideoDownloadUrl")
    @Operation(summary = "通过id获取音视频下载地址")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('system:audioAndVideo:query')")
    public CommonResult<Object> getDownloadUrl(@RequestParam("id") String id) {
        /**
         * 对应id的数据的字段"audio_andvideo_download_num"自增
         */
        audioAndVideoService.updateDownloadCount(id);
        return success(audioAndVideoService.getAudioAndVideoDownloadUrl(id));
    }
}
